package com.qf.rbac.annotation;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.qf.rbac.sys.entity.SysUser;
import com.qf.rbac.sys.entity.SysUserRole;
import com.qf.rbac.sys.service.ISysRoleDeptService;
import com.qf.rbac.sys.service.ISysUserRoleService;
import com.qf.rbac.utils.Constants;
import org.apache.shiro.SecurityUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

@Component
@Aspect
public class DataFilterAspect {

    @Autowired
    ISysUserRoleService sysUserRoleService;

    @Autowired
    ISysRoleDeptService sysRoleDeptService;

    // 该切点代表 ，所有加了 @DataFilter 的方法
    @Pointcut("@annotation(com.qf.rbac.annotation.DataFilter)")
    public void dataFilterPointCut(){}

    @Before("dataFilterPointCut()")
    public void before(JoinPoint joinPoint){
        // 获得加了 DataFilter 注解的方法的参数
        final Object arg = joinPoint.getArgs()[0];

        // 从注解当中，获取相关配置信息
        final MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        final DataFilter dataFilter = signature.getMethod().getAnnotation(DataFilter.class);
        final String deptField = dataFilter.deptId();

        String sql = getDataFilterSql(deptField);
        if (arg!=null && arg instanceof Map){
            ((Map) arg).put(Constants.SQL_FILTER,sql);
        }
    }

    // 根据当前登录用户的信息，查询该用户的数据权限（即该用户的角色中包含哪些部门id）
    private String getDataFilterSql(String deptIdField) {
        // 从shiro中获取当前登录用户信息
        final SysUser sysUser = (SysUser) SecurityUtils.getSubject().getPrincipal();

        // 判断当前用户是不是 Admin，如果是，则直接返回null
        if (sysUser.getUserId().equals(Constants.SUPER_ADMIN)) {
            return null;
        }

        // 1. 根据用户id 查 sys_user_role表，获取当前用的 roleId list
        final List<SysUserRole> userRoles = sysUserRoleService.list(new LambdaQueryWrapper<SysUserRole>().eq(SysUserRole::getUserId, sysUser.getUserId()));

        // 2. 遍历 roleId list， 查 sys_role_dept 获取每一个role对应的 deptId
        final Set<Long> detpResultSet = new HashSet<>();
        for (SysUserRole userRole : userRoles) {
            final List<Long> detpIdList = sysRoleDeptService.queryDeptIdList(userRole.getRoleId());
            detpResultSet.addAll(detpIdList);
        }

        // 3. 根据查询到的 detpResultSet 组装成 sql片段
        // 得到sql片段，例如， (3,4,5)
        final String sql = detpResultSet.stream().map(aLong -> aLong + "").collect(Collectors.joining(",", "(", ")"));

        return "("+deptIdField+" in"+sql+")";
    }
}
